from django.shortcuts import render,HttpResponse,get_object_or_404
from django.utils.safestring import mark_safe


from ..models import  Device,monitor



import logging
import  paramiko
import time
from datetime import datetime
import netmiko

from multiprocessing.pool import ThreadPool



logging.basicConfig(filename='test.log',filemode='a',level=logging.DEBUG)



def conf(request):

    if request.method == 'GET':

        ## 定义一个空字典
        data_dict={}

        ## 从前端获取数据；前端定义name属性
        search_data1 = request.GET.get("q1","")
        search_data2 = request.GET.get("q2", "")
        search_data3 = request.GET.get("q3", "")

        ## 判断是否有数据,如果有数据则加入到字典中
        if search_data1:
            data_dict["ip__contains"] = search_data1

        ## 判断是否有数据,如果有数据则加入到字典中
        if search_data2:
            data_dict["diqu__contains"] = search_data2

        ## 判断是否有数据,如果有数据则加入到字典中
        if search_data3:
            data_dict["vendor__contains"]= search_data3

        # 地区和设备厂商可以同时搜索
        if search_data2 and search_data3:
            data_dict = {
                "diqu": search_data2,
                "vendor": search_data3,
            }

        ## 定义当前页
        page = int(request.GET.get('page',1))

        ## 定义显示页码数据
        page_size = 5

        ## 定义每页开始位置
        start = (page - 1) * page_size

        ## 定义每页结束位置
        end = page * page_size

        device = Device.objects.filter(**data_dict)[start:end]

        ## 定义总数据
        total_count = Device.objects.filter(**data_dict).count()

        ## 计算出总页面
        total_page_count, div = divmod(total_count,page_size)
        if div:
             total_page_count += 1

        ## 计算出显示当前页的乾5页和后5页
        plus = 5

        if total_page_count <= 2 * plus + 1:
            # 当数据库中数据量少时，小于11页
            start_page = 1  # 开始页=1
            end_page = total_page_count  # 结束也=当前总页码
        else:
            # 当前页码<5时
            if page <= plus:
                start_page = 1
                end_page = 2 * plus + 1
            else:
                # 当前页码 + 要显示的页码 > 总页码时
                if (page + plus) > total_page_count:
                    start_page = total_page_count - 2 * plus
                    end_page = total_page_count
                else:
                    start_page = page - plus
                    end_page = page + plus

        # 页码
        # 定义一个列表
        page_str_list = []

        # 首页
        page_str_list.append('<li><a href="?page={}">首页</a></li>'.format(1))

        # 上一页
        if page > 1:
            prev = '<li><a href="?page={}">上一页</a></li>'.format(
            page - 1)
        else:
            prev = '<li><a href="?page={}">上一页</a></li>'.format(1)
            page_str_list.append(prev)

        # for循环，生成开始页和结束页
        for i in range(start_page, end_page + 1):
            # 如果i=当前页，在前端加个样式，如果不等于当前页则不添加
            if i == page:
                ele = '<li class="active"><a href="?page={}">{}</a></li>'.format(i, i)
            else:
                ele = '<li><a href="?page={}">{}</a></li>'.format(i, i)
                # 将生成出来的页码写入到列表中
            page_str_list.append(ele)

        # 下一页
        if page < total_page_count:
            prev = '<li><a href="?page={}">下一页</a></li>'.format(page + 1)
        else:
            prev = '<li><a href="?page={}">下一页</a></li>'.format(total_page_count)
        page_str_list.append(prev)

        # 尾页
        page_str_list.append('<li><a href="?page={}">尾页</a></li>'.format(total_page_count))

        page_string = mark_safe("".join(page_str_list))

        return render(request, "conf1.html", {"devices": device, "page_string": page_string,"search_data1":search_data1,"search_data2":search_data2,"search_data3":search_data3})


    elif request.method == "POST":
        result = []
        selected_devices_id = request.POST.getlist('device')

        ## 判断是否为空，如果有空则删除
        while '' in selected_devices_id:
            selected_devices_id.remove('')

        ##  从前端获取命令
        huawei_command = request.POST['huawei_command'].splitlines()
        cisco_command = request.POST['cisco_command'].splitlines()

        for x in selected_devices_id:
            try:
                dev = get_object_or_404(Device, pk=x)

                # if dev.vendor.lower() == 'cisco':
                #     cisco = {
                #             "device_type": "cisco_ios",
                #             "ip": dev.ip,
                #             "username": dev.username,
                #             "password": dev.password,
                #         }
                #     result.append(f'{dev.ip}上的运行结果:' + '\n')
                #     conn = netmiko.ConnectHandler(**cisco)
                #     output = conn.send_config_set(cisco_command)
                #     time.sleep(1)
                #     result.append(output + '\n\n\n')
                #
                # elif dev.vendor.lower() == 'huawei':
                #     huawei = {
                #             "device_type": "huawei",
                #             "ip": dev.ip,
                #             "username": dev.username,
                #             "password": dev.password,
                #         }
                #     result.append(f'{dev.ip}上的运行结果:' + '\n')
                #     conn = netmiko.ConnectHandler(**huawei)
                #     output = conn.send_config_set(huawei_command)
                #     time.sleep(1)
                #     result.append(output + '\n\n\n')

                ##  以下是多进程方式进行设备配置，但是有问题，多台设备返回的结果会不一样
                def cisco_ssh(ip, username, password,vendor):
                    cisco = {
                        "device_type": "cisco_ios",
                        "ip": ip,
                        "username": username,
                        "password": password,
                    }

                    huawei = {
                        "device_type": "huawei",
                        "ip": ip,
                        "username": username,
                        "password": password,
                    }

                    if vendor == 'cisco':
                        result.append(f'{ip}上的运行结果:' + '\n')
                        conn = netmiko.ConnectHandler(**cisco)
                        output = conn.send_config_set(cisco_command)
                        result.append(output + '\n\n\n\n')

                    elif vendor == 'huawei':
                        result.append(f'{ip}上的运行结果:' + '\n')
                        conn = netmiko.ConnectHandler(**huawei)
                        output = conn.send_config_set(huawei_command)
                        result.append(output + '\n\n\n\n')

                pool = ThreadPool(20)
                pool.apply_async(cisco_ssh, args=(dev.ip, dev.username, dev.password,dev.vendor.lower()))
                pool.close()
                pool.join()
            except Exception as e:
                pass
        result = '\n'.join(result)
        return render(request, "verify_config.html", {'result': result})















































